package com.mz361.stdapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mz361.common.data.PageSort;
import com.mz361.common.utils.DateUtils;
import com.mz361.common.utils.RedisUtil;
import com.mz361.common.utils.StringUtil;
import com.mz361.stdapi.domain.PlanSearch;
import com.mz361.stdapi.domain.StandardPlan;
import com.mz361.stdapi.repository.StandardPlanRepository;
import com.mz361.stdapi.service.StandardPlanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author niceale
 * @ date 2024/04/26
 */
@Service
public class StandardPlanServiceImpl implements StandardPlanService {


    @Autowired
    private StandardPlanRepository standardPlanRepository;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 根据ID查询数据
     *
     * @param id 主键ID
     */
    @Override
    public StandardPlan getById(Long id) {
        return standardPlanRepository.findById(id).orElse(null);
    }

    @Override
    public Long getStandardPlanLikeCcs(String ccs) {
        return standardPlanRepository.getStandardPlanLikeCcs(ccs);
    }

    @Override
    public StandardPlan getByStandardPlanNo(String standardPlanNo) {
        return standardPlanRepository.getStandardPlanByStandardPlanNo(standardPlanNo);
    }

    /**
     * 获取分页列表数据
     *
     * @param example 查询实例
     * @return 返回分页数据
     */
    @Override
    public Page<StandardPlan> getPageList(Example<StandardPlan> example) {
        // 创建分页对象
        PageRequest page = PageSort.pageRequest();
        return standardPlanRepository.findAll(example, page);
    }

    @Override
    public Page<StandardPlan> getPageList(PlanSearch planSearch) {
        String md5str = StringUtil.md5(JSONObject.toJSONString(planSearch));
        if (!redisUtil.exists("STANDARD:PLAN:" + md5str)) {
            if (StringUtil.notEmpty(planSearch.getDurDate())) {
                String startDate = "";
                if ("0".equals(planSearch.getDurDate())) {
                    startDate = DateUtils.format(DateUtils.getPreMonthDay(new Date()), "yyyy-MM-dd");
                }
                if ("1".equals(planSearch.getDurDate())) {
                    startDate = DateUtils.format(DateUtils.getPreMonthDay(new Date(), -3), "yyyy-MM-dd");
                }
                if ("2".equals(planSearch.getDurDate())) {
                    startDate = DateUtils.format(DateUtils.getPreMonthDay(new Date(), -6), "yyyy-MM-dd");
                }
                if ("3".equals(planSearch.getDurDate())) {
                    startDate = DateUtils.format(DateUtils.getPreMonthDay(new Date(), -24), "yyyy-MM-dd");
                }
                if ("4".equals(planSearch.getDurDate())) {
                    startDate = DateUtils.format(DateUtils.getPreMonthDay(new Date(), -36), "yyyy-MM-dd");
                }
                planSearch.setDurDate(startDate);
            }
            PageRequest page = PageRequest.of(planSearch.getPageNo(), planSearch.getPageSize(), Sort.Direction.DESC, "scheduledDate");
            Page<StandardPlan> plans = standardPlanRepository.findAll(mySpecification(planSearch), page);
            redisUtil.setexValue("STANDARD:PLAN:" + md5str, 300, JSONObject.toJSONString(plans));
            return plans;
        } else {
            PageRequest page = PageRequest.of(planSearch.getPageNo(), planSearch.getPageSize(), Sort.Direction.DESC, "scheduledDate");
            return convertJsonStringToPage(redisUtil.getValue("STANDARD:PLAN:" + md5str), page);
        }
    }

    @Override
    public List<StandardPlan> getStandardPlanList() {
        return standardPlanRepository.findAll();
    }

    @Override
    public List<String> getCCSs() {
        return standardPlanRepository.getCCSs();
    }

    /**
     * 保存数据
     *
     * @param standardPlan 实体对象
     */
    @Override
    public StandardPlan save(StandardPlan standardPlan) {
        standardPlan = standardPlanRepository.save(standardPlan);
        return standardPlan;
    }

    public Specification<StandardPlan> mySpecification(PlanSearch planSearch) {
        return new Specification<StandardPlan>() {
            @Override
            public Predicate toPredicate(Root<StandardPlan> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                // 添加第一个字段的匹配条件
                if (StringUtil.notEmpty(planSearch.getKeyword())) {
                    predicates.add(cb.like(root.get("title"), "%" + planSearch.getKeyword() + "%"));
                }
                // 添加第二个字段的匹配条件
                if (StringUtil.notEmpty(planSearch.getCcs())) {
                    predicates.add(cb.like(root.get("CCS"), "%" + planSearch.getCcs() + ".%"));
                }
                // 添加第二个字段的匹配条件
                if (StringUtil.notEmpty(planSearch.getProgress())) {
                    predicates.add(cb.equal(root.get("progress"), planSearch.getProgress()));
                }
                if (StringUtil.notEmpty(planSearch.getDurDate())) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("scheduledDate"), planSearch.getDurDate()));
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }

    public static Page<StandardPlan> convertJsonStringToPage(String jsonString, Pageable pageable) {
        // 解析JSON字符串为JSONObject
        JSONObject jsonObject = JSON.parseObject(jsonString);

        // 假设JSON对象中有一个名为"content"的字段，它是一个包含StandardPlan对象的数组
        JSONArray jsonArray = jsonObject.getJSONArray("content");
        Long totalElements = jsonObject.getLong("totalElements");
        // 创建StandardPlan列表
        List<StandardPlan> standardPlans = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject planObject = jsonArray.getJSONObject(i);
            // 将每个JSONObject转换为StandardPlan对象，这里需要自定义转换逻辑
            StandardPlan standardPlan = JSONObject.parseObject(planObject.toJSONString(), StandardPlan.class);
            standardPlans.add(standardPlan);
        }

        // 创建Page对象
        return new PageImpl<>(standardPlans, pageable, totalElements);
    }


}

